/**
 * @file proximity_sensor_common.c
 * @brief 通用接近传感器监控模块实现
 * 
 * 该模块提供接近传感器的通用功能，包括：
 * 1. GPIO初始化和清理
 * 2. 传感器状态监控
 * 3. 线程安全的状态查询
 * 4. 错误处理和恢复
 * 5. 调试功能
 * 
 * @author 伞控无人机项目组
 * @date 2023
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
#include <stdint.h>
#include "proximity_sensor_common.h"
#include "gpio_lib.h"
#include "log_modules.h"

// 预定义的传感器配置
const proximity_sensor_config_t PROXIMITY_SENSOR_1_CONFIG = {
    .gpio_pin = "4_A3_d",           // 接近传感器GPIO4_A3，编号131 (432+8+3)
    .sensor_name = "接近传感器1",
    .log_module = LOG_MODULE_PROX1,
    .log_data_type = LOG_DATA_PROX_DIST,
    .log_state_type = LOG_STATE_SENS_STAT
};

const proximity_sensor_config_t PROXIMITY_SENSOR_2_CONFIG = {
    .gpio_pin = "2_D4_d",           // 第二个接近传感器使用的GPIO引脚
    .sensor_name = "接近传感器2",
    .log_module = LOG_MODULE_PROX2,
    .log_data_type = LOG_DATA_PROX_DIST,
    .log_state_type = LOG_STATE_SENS_STAT
};

/**
 * @brief 初始化接近传感器
 * 
 * @param handle 传感器句柄指针
 * @param config 传感器配置指针
 * @return int 成功返回0，失败返回负数
 */
int proximity_sensor_init(proximity_sensor_handle_t *handle, const proximity_sensor_config_t *config) {
    if (!handle || !config) {
        return -1;
    }
    
    // 复制配置
    memcpy(&handle->config, config, sizeof(proximity_sensor_config_t));
    
    // 初始化状态
    memset(&handle->state, 0, sizeof(proximity_sensor_state_t));
    handle->state.is_initialized = 0;
    handle->thread_running = 0;
    
    // 初始化互斥锁
    if (pthread_mutex_init(&handle->mutex, NULL) != 0) {
        return -2;
    }
    
    // 初始化GPIO
    gpio_handle_t *gpio = malloc(sizeof(gpio_handle_t));
    if (!gpio) {
        pthread_mutex_destroy(&handle->mutex);
        return -3;
    }
    
    if (gpio_init(gpio, config->gpio_pin, GPIO_DIR_INPUT, GPIO_EDGE_BOTH) != 0) {
        free(gpio);
        pthread_mutex_destroy(&handle->mutex);
        return -4;
    }
    
    handle->gpio_handle = gpio;
    handle->state.is_initialized = 1;
    
    LOG_INFO(LOG_TO_FILE, config->log_module, "%s 初始化成功，GPIO: %s", 
             config->sensor_name, config->gpio_pin);
    
    return 0;
}

/**
 * @brief 清理接近传感器资源
 * 
 * @param handle 传感器句柄指针
 */
void proximity_sensor_cleanup(proximity_sensor_handle_t *handle) {
    if (!handle) {
        return;
    }
    
    // 停止监控线程
    handle->thread_running = 0;
    
    // 清理GPIO
    if (handle->gpio_handle) {
        gpio_cleanup((gpio_handle_t*)handle->gpio_handle);
        free(handle->gpio_handle);
        handle->gpio_handle = NULL;
    }
    
    // 销毁互斥锁
    pthread_mutex_destroy(&handle->mutex);
    
    handle->state.is_initialized = 0;
    
    LOG_INFO(LOG_TO_FILE, handle->config.log_module, "%s 资源清理完成", 
             handle->config.sensor_name);
}

/**
 * @brief 读取传感器状态
 * 
 * @param handle 传感器句柄指针
 * @return int 成功返回传感器状态，失败返回负数
 */
int proximity_sensor_read_state(proximity_sensor_handle_t *handle) {
    if (!handle || !handle->state.is_initialized) {
        return -1;
    }
    
    gpio_handle_t *gpio = (gpio_handle_t*)handle->gpio_handle;
    int state = gpio_read(gpio);
    
    if (state < 0) {
        handle->state.error_count++;
        LOG_WARN(LOG_TO_FILE, handle->config.log_module, 
                 "%s 读取失败，错误计数: %d", 
                 handle->config.sensor_name, handle->state.error_count);
        return -2;
    }
    
    // 重置错误计数
    handle->state.error_count = 0;
    
    // 更新状态
    pthread_mutex_lock(&handle->mutex);
    handle->state.sensor_state = state;
    handle->state.timestamp = (uint32_t)time(NULL);
    pthread_mutex_unlock(&handle->mutex);
    
    return state;
}

/**
 * @brief 获取传感器状态（线程安全）
 * 
 * @param handle 传感器句柄指针
 * @param state 保存状态的结构体指针
 * @return int 成功返回0，失败返回负数
 */
int proximity_sensor_get_state(proximity_sensor_handle_t *handle, proximity_sensor_state_t *state) {
    if (!handle || !state) {
        return -1;
    }
    
    pthread_mutex_lock(&handle->mutex);
    memcpy(state, &handle->state, sizeof(proximity_sensor_state_t));
    pthread_mutex_unlock(&handle->mutex);
    
    return 0;
}

/**
 * @brief 调试GPIO状态
 * 
 * @param handle 传感器句柄指针
 */
void proximity_sensor_debug_gpio(proximity_sensor_handle_t *handle) {
    if (!handle || !handle->state.is_initialized) {
        return;
    }
    
    gpio_handle_t test_gpio;
    int state;
    
    LOG_INFO(LOG_TO_FILE, handle->config.log_module, 
             "开始调试GPIO %s", handle->config.gpio_pin);
    
    // 初始化测试GPIO
    if (gpio_init(&test_gpio, handle->config.gpio_pin, GPIO_DIR_INPUT, GPIO_EDGE_BOTH) != 0) {
        LOG_ERROR(LOG_TO_FILE, handle->config.log_module, 
                  "调试：GPIO初始化失败");
        return;
    }
    
    // 连续读取10次状态
    for (int i = 0; i < 10; i++) {
        state = gpio_read(&test_gpio);
        if (state >= 0) {
            LOG_INFO(LOG_TO_FILE, handle->config.log_module, 
                     "调试读取 %d/10: GPIO值=%d, %s", 
                     i+1, state, 
                     state == 0 ? "检测到物体(有效)" : "未检测到物体(无效)");
        } else {
            LOG_ERROR(LOG_TO_FILE, handle->config.log_module, 
                      "调试读取 %d/10: 读取失败", i+1);
        }
        usleep(500000);  // 500ms间隔
    }
    
    gpio_cleanup(&test_gpio);
    LOG_INFO(LOG_TO_FILE, handle->config.log_module, "GPIO调试完成");
}

/**
 * @brief 接近传感器监控线程函数
 * 
 * @param arg 线程参数（proximity_sensor_handle_t指针）
 * @return void* 始终返回NULL
 */
void* proximity_sensor_monitor_thread(void *arg) {
    proximity_sensor_handle_t *handle = (proximity_sensor_handle_t*)arg;
    if (!handle) {
        return NULL;
    }
    
    LOG_INFO(LOG_TO_FILE, handle->config.log_module, 
             "监控线程启动: %s", handle->config.sensor_name);
    
    // 读取初始状态
    int sensor_state = proximity_sensor_read_state(handle);
    if (sensor_state >= 0) {
        LOG_INFO(LOG_TO_FILE, handle->config.log_module, 
                 "%s 初始状态: GPIO值=%d, %s", 
                 handle->config.sensor_name, sensor_state,
                 sensor_state == 0 ? "检测到物体(有效)" : "未检测到物体(无效)");
    } else {
        LOG_ERROR(LOG_TO_FILE, handle->config.log_module, 
                  "%s 读取初始状态失败", handle->config.sensor_name);
    }
    
    // 设置线程运行标志
    handle->thread_running = 1;
    
    // 主循环：持续监测传感器状态
    while (handle->thread_running) {
        // 读取传感器状态
        sensor_state = proximity_sensor_read_state(handle);
        
        if (sensor_state >= 0) {
            // 使用标准化数据记录格式
            LOG_INFO(LOG_TO_FILE, handle->config.log_module, 
                     "[%s] distance=%.2f", handle->config.log_data_type, (float)sensor_state);
            
            // 记录传感器状态
            LOG_INFO(LOG_TO_FILE, handle->config.log_module, 
                     "[%s] status=OK", handle->config.log_state_type);
            
            // 输出当前状态信息
            LOG_INFO(LOG_TO_FILE, handle->config.log_module, 
                     "%s 当前状态: GPIO值=%d, %s", 
                     handle->config.sensor_name, sensor_state,
                     sensor_state == 0 ? "检测到物体(有效)" : "未检测到物体(无效)");
        } else {
            LOG_WARN(LOG_TO_FILE, handle->config.log_module, 
                     "%s 读取失败", handle->config.sensor_name);
            LOG_INFO(LOG_TO_FILE, handle->config.log_module, 
                     "[%s] status=ERROR", handle->config.log_state_type);
            
            // 如果连续错误过多，尝试重新初始化GPIO
            if (handle->state.error_count >= 10) {
                LOG_ERROR(LOG_TO_FILE, handle->config.log_module, 
                          "%s 连续错误过多，尝试重新初始化GPIO", 
                          handle->config.sensor_name);
                
                // 清理并重新初始化
                if (handle->gpio_handle) {
                    gpio_cleanup((gpio_handle_t*)handle->gpio_handle);
                    free(handle->gpio_handle);
                }
                
                gpio_handle_t *gpio = malloc(sizeof(gpio_handle_t));
                if (gpio && gpio_init(gpio, handle->config.gpio_pin, 
                                     GPIO_DIR_INPUT, GPIO_EDGE_BOTH) == 0) {
                    handle->gpio_handle = gpio;
                    handle->state.error_count = 0;
                    LOG_INFO(LOG_TO_FILE, handle->config.log_module, 
                             "%s GPIO重新初始化成功", handle->config.sensor_name);
                } else {
                    if (gpio) free(gpio);
                    LOG_ERROR(LOG_TO_FILE, handle->config.log_module, 
                              "%s GPIO重新初始化失败", handle->config.sensor_name);
                }
            }
            
            sleep(1);
            continue;
        }
        
        // 休眠一段时间，避免过于频繁的读取
        usleep(500000);  // 500ms
    }
    
    LOG_INFO(LOG_TO_FILE, handle->config.log_module, 
             "%s 监控线程退出", handle->config.sensor_name);
    return NULL;
}

/**
 * @brief 停止接近传感器监控
 * 
 * @param handle 传感器句柄指针
 */
void proximity_sensor_stop(proximity_sensor_handle_t *handle) {
    if (!handle) {
        return;
    }
    
    LOG_INFO(LOG_TO_FILE, handle->config.log_module, 
             "%s 停止中", handle->config.sensor_name);
    
    handle->thread_running = 0;
} 